package mysql

import (
	"gitee.com/xiedongji/antgo/cpts/xlog"
	gormMysqlDriver "gorm.io/driver/mysql"
	"gorm.io/gorm"
	gormLogger "gorm.io/gorm/logger"
	"time"
)

/* ============================================================ *
 * 功能:mysql
 * ============================================================ */
const cptName = "mysql"

var instance *Instance
var conns = make(map[string]*gorm.DB)

type Instance struct {
	Items map[string]connCfg `yaml:"items"`
}

type connCfg struct {
	Dsn                       string              `yaml:"dsn"`
	MaxIdleConns              int                 `yaml:"max_idle_conns"`
	MaxOpenConns              int                 `yaml:"max_open_conns"`
	ConnMaxLifetime           time.Duration       `yaml:"conn_max_lifetime"`
	SlowThreshold             time.Duration       `yaml:"slow_threshold"`
	Colorful                  bool                `yaml:"colorful"`
	IgnoreRecordNotFoundError bool                `yaml:"ignore_record_not_found_error"`
	LogLevel                  gormLogger.LogLevel `yaml:"log_level"`
}

func (i *Instance) GetName() string {
	return cptName
}

func (i *Instance) Run() error {
	instance = i
	for key, connCfg := range i.Items {
		zLog := xlog.Logger(cptName, key)
		iLog := NewMysqlLogger(*zLog, gormLogger.Config{
			SlowThreshold:             connCfg.SlowThreshold,             // 慢 SQL 阈值
			Colorful:                  connCfg.Colorful,                  // 禁用彩色打印
			LogLevel:                  connCfg.LogLevel,                  // 日志级别
			IgnoreRecordNotFoundError: connCfg.IgnoreRecordNotFoundError, // 忽略ErrRecordNotFound（记录未找到）错误
		})

		// 开启连接
		conn, err := gorm.Open(
			gormMysqlDriver.Open(connCfg.Dsn),
			&gorm.Config{
				Logger:                 iLog,
				SkipDefaultTransaction: true,
			},
		)
		if err != nil {
			xlog.Logger(cptName, "mysql").Error().Err(err).Send()
			continue
		}

		// 配置信息
		sqlDB, err := conn.DB()
		if err != nil {
			xlog.Logger(cptName, "mysql").Error().Err(err).Send()
			continue
		}

		sqlDB.SetMaxIdleConns(connCfg.MaxIdleConns)
		sqlDB.SetMaxOpenConns(connCfg.MaxOpenConns)
		sqlDB.SetConnMaxLifetime(connCfg.ConnMaxLifetime)

		conns[key] = conn
	}

	return nil
}

// ====================== 业务板块 ======================
func Get(name string) *gorm.DB {
	if conn, ok := conns[name]; ok {
		return conn
	}

	return nil
}

func MainDB() *gorm.DB {
	return Get("main")
}
